JavaScript is an easy to learn programming language. It also uses lots of functional programming features that make our lives easier.
In this article, we look at the functional programming characteristics of JavaScript functions.
High Order Functions
Higher-order functions are functions that take other functions arguments or return functions in their results.
This means that JavaScript code can take callbacks or return functions, for example.
Examples of higher-order functions include the array instance’s map
method, which we can call by writing something like the following code:
const arr = [1, 2, 3].map(a => a * 2);
In the code above, we called the map
method with the callback functiona => a * 2
,
Then the map
method will call the callback to map each entry from its original value to a new value by doubling each entry, add each mapped entry in a new array and return the new array.
There’re many other array instance methods that take callbacks, include some
, every
, find
, findIndex
, filter
etc.
We can create a function that returns a function by writing something like:
const returnAdd = () => (a, b) => a + b;
const result = returnAdd()(1, 2);
In the code above, we have the returnAdd
function, which returns a function that adds 2 numbers together.
Then we can call the returned function to add 2 numbers by first calling the returnAdd
function to return the function to add the numbers, then call the returned function to add the numbers and return the sum.
Therefore, result
should be 3 in the example above.
First-Class Function
First-class functions are functions that are treated like any other object. They can be stored in variables, passed around, returned from other functions, and hold their own properties.
As we can see from the previous section, functions can be passed into another function and functions can also be returned as arguments in a function.
In addition, they can also have properties. For instance, we can set properties on a function by writing something like the following:
const foo = () => {};
foo.bar = 1;
In the example above, we have the foo
function defined in the first line. Then we create the bar
property on the foo
function and then set its value to 1.
When we log the value of foo.bar
, we should see that foo.bar
is 1.
As we can see functions are just like any object in that they can have their own properties.
This is more useful for constructor functions when we need to create static properties of methods.
For instance, if we have the following constructor function:
function Person(name) {
this.name = name;
}
Then we can define a static method for it as follows:
Person.greet = () => console.log('hello');
Now we have a static greet
method, which we can call on Person
. Then we can call it as follows:
Person.greet();
And we see that 'hello'
is logged in the console.
The same thing can be done to add properties to the function as we saw from the previous example.
Since JavaScript classes are just syntactic sugar on top of constructor functions. We can define static members of JavaScript classes the same way as we did with constructor functions.
For instance, if we have the following class:
class Person {
constructor(name) {
this.name = name;
}
}
Then we can define a static method on it as follows:
Person.greet = () => console.log('hello');
Recursion
Recursion is where a function calls itself. Like most languages, we can define a recursive function. Many loops can be rewritten in a recursive way. In some functional languages, using recursion is the default way to loop through items.
However, they’re harder to understand, so to make reading the code easy, we stick with loops and array methods for iteration and manipulating data.
For instance, we the following loop:
for (let i = 0; i <= 4; i++) {
console.log(i);
}
produces the same result as the following recursive function:
const loop = (i = 0) => {
console.log(i);
if (i === 4) {
return;
}
loop(i + 1);
}
loop();
As we can see, the loop is much shorter and easier to understand.
With the recursive loop
function, we have to run the console.log
like we did with the for
loop, but also have to check the base case which when i
is 4, and then we have to end the loop if i
reaches 4.
Otherwise, we let the function call itself.
It’s more useful for traversing tree structures with indefinite depth levels.
Conclusion
In JavaScript, functions are treated like any other object. We can set properties to it, pass it in as an argument, and functions can return functions.
Recursion is also an important part of functional programming. We can use it to create a function that calls itself.